import math, random

#========================================

def corners(rect):
    return (rect.topleft,
            (rect.topright[0]-1, rect.topright[1]),
            (rect.bottomleft[0], rect.bottomleft[1]-1),
            (rect.bottomright[0]-1, rect.bottomright[1]-1))

#========================================

def perimeter(rect):
    for y in (rect.top, rect.bottom-1):
        for x in xrange(rect.left, rect.left+rect.w):
            yield x,y
    for x in (rect.left, rect.right-1):
        for y in xrange(rect.top+1, rect.top+rect.h):
            yield x,y

#========================================

def neighbors((x,y)):
    yield x+1, y
    yield x-1, y
    yield x, y+1
    yield x, y-1
    yield x+1, y+1
    yield x+1, y-1
    yield x-1, y+1
    yield x-1, y-1

#========================================

def displacement(dir):
    dx, dy = 0, 0
    if 'north' in dir:
        dy = -1
    if 'south' in dir:
        dy = 1
    if 'east' in dir:
        dx = 1
    if 'west' in dir:
        dx = -1
    return dx, dy

#========================================

def adjacentTiles(tile):
    if not tile:
        yield None
        return

    map = tile.map
    c, r = tile.col, tile.row
    for i in (-1, 0, 1):
        for j in (-1, 0, 1):
            if (i,j) == (0,0):
                continue
            if c+i < 0 or c+i >= map.cols or r+j < 0 or r+j >= map.rows:
                continue
            yield map[(c+i, r+j)]

#========================================

def thirdperson(verb):
    if verb.endswith('ch') or verb.endswith('sh') or verb.endswith('x'):
        return verb + 'es'
    elif verb.endswith('y'):
        return verb[:-1] + 'ies'
    return verb + 's'

#========================================

def magnitude(vector):
    sumsqs = 0.0
    for component in vector:
        sumsqs += component**2
    return math.sqrt(sumsqs)

#========================================

def difference(vector1, vector2):
    return map(lambda (x,y): x-y, zip(vector1, vector2))

#========================================

def distance(vector1, vector2):
    if len(vector1) != len(vector2):
        raise ValueError('Vectors must have same number of dimensions!')
    return magnitude(difference(vector1, vector2))

#========================================

def signVector(vector):
    return map(lambda x: x < 0 and -1 or (x > 0 and 1 or 0), vector)

#========================================

def chooseWeighted(weightedList):
    totalWeight = sum([w for (x,w) in weightedList])
    weightSoFar = 0
    r = random.randint(0, totalWeight-1)
    for x,w in weightedList:
        if r < weightSoFar + w:
            return x
        weightSoFar += w
    assert(False)

